<html>
  <head>
  </head>
  <body>
    <div class="block">
      Grid Test
    </div>
    <div class="block">
      <canvas id="cardBoard" width="480" height="640"></canvas>
    </div>
    <script>
      var CardBoard = new function () 
      {
        this.board = 0;
        this.boardStartWidth = 4;
        this.boardHalf = 6;
        this.selected = -1;
        this.boardCell = -1;
        this.turn = 0;
        this.cards = [];
        this.selectedSupported = [];
        this.neighbourFunctions = [];
        function getElemOffset( element )
        {
          var offsetX = 0, offsetY = 0;
          if (element.offsetParent !== undefined) {
            do {
              offsetX += element.offsetLeft;
              offsetY += element.offsetTop;
            } while ((element = element.offsetParent));
          }
          return { x: offsetX, y: offsetY };
        }
        this.getSupportedIndices = function()
        {
          var cW = CardBoard.boardStartWidth+CardBoard.boardHalf-1;
          var cH = CardBoard.boardHalf*2-1;
          var currW = CardBoard.boardStartWidth;
          var result = [];
          for (var y=0; y<cH;y++)
          {
            var xOffset = Math.floor((cW - currW)*0.5); 
            for (var x=0; x<currW; x++)
            {
              result[result.length] = (y*cW)+xOffset+x;
            }
            if (y<CardBoard.boardHalf-1)
            {
              currW = currW + 1;
            }
            else
            {
              currW = currW -1;
            }
          }
          return result;
        }
        
        this.getNeighbourIndices0 = function(i)
        {
          var cW = CardBoard.boardStartWidth+CardBoard.boardHalf-1;
          var cH = CardBoard.boardHalf*2-1;
          var t = 0;
          if (Math.floor(i/cW)%2 == 1)
          {
            t=-1;
          }
          return [i-cW+t,i-cW+1+t, i-1, i, i+1,  i+cW+t,i+cW+1+t];
        }
        
        this.getNeighbourIndices1 = function(i)
        {
          var cW = CardBoard.boardStartWidth+CardBoard.boardHalf-1;
          var cH = CardBoard.boardHalf*2-1;
          var t = 0;
          if (Math.floor(i/cW)%2 == 1)
          {
            t=-1;
          }
          var res = [];
          for (var j=0; j<7; j++)
          {
            res[res.length] = i+cW*(j-3);
          }
          return res;
        }
        this.getNeighbourIndices2 = function(i)
        {
          var cW = CardBoard.boardStartWidth+CardBoard.boardHalf-1;
          var cH = CardBoard.boardHalf*2-1;
          var t = 0;
          if (Math.floor(i/cW)%2 == 1)
          {
            t=-1;
          }
          return [i-cW*2, i-cW+t,i-cW+1+t, i,  i+cW+t,i+cW+1+t, i+cW*2];
        }
        this.getGridPos = function(p)
        {
          var canvas = document.getElementById('cardBoard');
          var cW = CardBoard.boardStartWidth+CardBoard.boardHalf-1;
          var cH = CardBoard.boardHalf*2-1;
          var w = canvas.width/cW;
          var h = canvas.height/cH;
          var x = p.x/w;
          var cY = Math.floor(p.y/h);
          if (cY%2==0)
          {
            x=x-0.5;
          }
          var cX = Math.floor(x);
          
          return cX+cY*cW;
        }
        this.getSame = function(a,b)
        {
          var result = [];
          var aIndex = 0;
          var bIndex = 0;
          while (aIndex < a.length && bIndex < b.length)
          {
            if (a[aIndex] == b[bIndex])
            {
              result[result.length] = a[aIndex]
              aIndex = aIndex + 1;
              bIndex = bIndex + 1;
            }
            else if (a[aIndex] < b[bIndex])
            {
              aIndex = aIndex + 1;
            }
            else
            {
              bIndex = bIndex + 1;
            }
          }
          return result;
        }
        this.getWorldPos = function(i)
        {
          var canvas = document.getElementById('cardBoard');
          var cW = CardBoard.boardStartWidth+CardBoard.boardHalf-1;
          var cH = CardBoard.boardHalf*2-1;
          var w = canvas.width/cW;
          var h = canvas.height/cH;
          
          var x = i%cW;
          var y = Math.floor(i/cW);
          if (y%2==0)
          {
            x=x+0.5;
          }
          return { x:x*w,y:y*h};
        }
        this.inputMove = function(p)
        { 
          CardBoard.boardCell = CardBoard.getGridPos(p);
          if (CardBoard.selected == -1)
          {
            for (var i=0; i<CardBoard.cards.length; i++)
            {
              if (CardBoard.cards[i].i == CardBoard.boardCell && CardBoard.cards[i].t != 0)
              {
                CardBoard.selectedSupported = CardBoard.getSame(CardBoard.cards[i].sf(CardBoard.boardCell), CardBoard.board);
                var tmpCard = CardBoard.cards[i];
                CardBoard.cards[i] = CardBoard.cards[CardBoard.cards.length-1];
                CardBoard.cards[CardBoard.cards.length-1] = tmpCard;
                CardBoard.selected = CardBoard.cards.length-1;
                
                var worldPos = CardBoard.getWorldPos(CardBoard.boardCell);
                CardBoard.cards[CardBoard.selected].offset = {x:p.x - worldPos.x, y:p.y - worldPos.y};
                break;
              }
            }
          }
          if (CardBoard.selected != -1 && CardBoard.cards[CardBoard.selected].v == CardBoard.turn)
          {
            CardBoard.cards[CardBoard.selected].p.x = p.x-CardBoard.cards[CardBoard.selected].offset.x;
            CardBoard.cards[CardBoard.selected].p.y = p.y-CardBoard.cards[CardBoard.selected].offset.y;
          }
        }
        this.inputEnd = function()
        { 
          if (CardBoard.boardCell == 0)
          {
            CardBoard.turn = (CardBoard.turn+1)%2;
            for (var i=0; i<CardBoard.cards.length; i++)
            {
              CardBoard.cards[i].t = 1;
            }
            CardBoard.selected = -1;
          }
          if (CardBoard.selected != -1)
          {
            if (CardBoard.cards[CardBoard.selected].v != CardBoard.turn)
            {
                CardBoard.selected = -1;
            }
          }
          var canMove = false;
          if (CardBoard.selected != -1)
          {
            for (var i=0; i<CardBoard.selectedSupported.length; i++)
            {
              if (CardBoard.boardCell == CardBoard.selectedSupported[i])
              {
                canMove = true;
                break;
              }
            }
          }
          if (canMove)
          {
            for (var i=0; i<CardBoard.cards.length; i++)
            {
              if (CardBoard.cards[i].i == CardBoard.boardCell)
              {
                if (CardBoard.cards[i].v != CardBoard.cards[CardBoard.selected].v)
                {
                  CardBoard.cards[i] = CardBoard.cards[CardBoard.selected];
                  CardBoard.selected = i;
                  CardBoard.cards.pop();
                }
                else
                {
                  canMove = false;
                }
                break;
              }
            }
          }
          if (canMove)
          {
            CardBoard.cards[CardBoard.selected].i = CardBoard.boardCell;
            CardBoard.cards[CardBoard.selected].t = 0;
          }
          CardBoard.boardCell = -1;
          CardBoard.selected = -1;
          CardBoard.selectedSupported = [];
        }
        this.init = function()
        {
          CardBoard.neighbourFunctions[0] = CardBoard.getNeighbourIndices0;
          CardBoard.neighbourFunctions[1] = CardBoard.getNeighbourIndices1;
          CardBoard.neighbourFunctions[2] = CardBoard.getNeighbourIndices2;
          CardBoard.board = CardBoard.getSupportedIndices();
          for (var i=0; i<3; i++)
          {
            CardBoard.cards[CardBoard.cards.length] = { t:1, i:CardBoard.board[i],v:0, sf:CardBoard.neighbourFunctions[i] };
            CardBoard.cards[CardBoard.cards.length] = { t:1, i:CardBoard.board[CardBoard.board.length - i - 1],v:1, sf:CardBoard.neighbourFunctions[i]  };
          }
          for (var i=0; i<CardBoard.cards.length; i++)
          {
            CardBoard.cards[i].p = CardBoard.getWorldPos(CardBoard.cards[i].i);
          }
          var canvas = document.getElementById('cardBoard');
          
          var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0));
          if (!isTouch)
          {
            var inputEvent = function(event)
            {
              if (event.which == 1)
              {
                var offset = getElemOffset(canvas);
                var p = { 
                  x : event.pageX - offset.x,
                  y : event.pageY - offset.y
                };
                CardBoard.inputMove(p);
                event.preventDefault();
              }
            }
            var endInputEvent = function(){CardBoard.inputEnd();}
            canvas.addEventListener('mousedown', inputEvent);
            canvas.addEventListener('mousemove', inputEvent);
            canvas.addEventListener('mouseup',endInputEvent);
            canvas.addEventListener('mouseout',endInputEvent);
          }
          else
          {
            var inputEvent = function(event)
            {
              if (event.targetTouches.length == 1) 
              {
                var offset = getElemOffset(canvas);
                var p = { 
                  x : event.targetTouches[0].pageX - offset.x,
                  y : event.targetTouches[0].pageY - offset.y
                };
                CardBoard.inputMove(p);
                event.preventDefault();
              }
            }
            var endInputEvent = function(){CardBoard.inputEnd();}
            canvas.addEventListener('touchstart',inputEvent );
            canvas.addEventListener('touchmove', inputEvent );
            canvas.addEventListener('touchend',endInputEvent);
            canvas.addEventListener('touchcancel',endInputEvent);
          }
          var timeHandle = setInterval(function(){CardBoard.redraw()}, 60);
        }
        this.redraw = function()
        {
          var canvas = document.getElementById('cardBoard');
          var ctx = canvas.getContext("2d");
          ctx.fillStyle = "#999999";
          ctx.fillRect(0, 0, canvas.width, canvas.height);
       
          var cW = CardBoard.boardStartWidth+CardBoard.boardHalf-1;
          var cH = CardBoard.boardHalf*2-1;
          var w = canvas.width/cW;
          var h = canvas.height/cH;
          {
            var pos = CardBoard.getWorldPos(0);
            
            var colorVal = 0.8;
            ctx.fillStyle = "#000000";
            ctx.fillRect(pos.x+2, pos.y+2, w-4, h-4);
            if (CardBoard.boardCell == 0)
            {
              colorVal = colorVal + 0.2;
              
            }
            
            if (CardBoard.turn == 0)
            {
              ctx.fillStyle = "rgb("+Math.floor(colorVal*255) + ","+Math.floor(colorVal*100) +","+Math.floor(colorVal*100) +")";
            }
            else
            {
              ctx.fillStyle = "rgb("+Math.floor(colorVal*100) + ","+Math.floor(colorVal*255) + ","+Math.floor(colorVal*100) +")";
            }
            ctx.fillRect(pos.x+4, pos.y+4, w-8, h-8);
            
            ctx.font = "12px sans serif";
            ctx.fillStyle = "#000000";
            ctx.textAlign = "center";
            ctx.textBaseline = "middle"; 
            ctx.fillText("turn", pos.x+w*0.5, pos.y+h*0.5);
          }
          
          for (var i=0; i<CardBoard.selectedSupported.length;i++)
          {
            var index = CardBoard.selectedSupported[i];
            var pos = CardBoard.getWorldPos(index);
            if (index == CardBoard.boardCell)
            {
              ctx.fillStyle = "#FFFFFF";
            }
            else
            {
              ctx.fillStyle = "#888800";
            }
            ctx.fillRect(pos.x, pos.y, w, h);
          }
          
          for (var i=0; i<CardBoard.board.length;i++)
          {
            var index = CardBoard.board[i];
            var pos = CardBoard.getWorldPos(index);
            ctx.fillStyle = "#000000";
            ctx.fillRect(pos.x+2, pos.y+2, w-4, h-4);
            
            ctx.fillStyle = "#333333";
            ctx.fillRect(pos.x+4, pos.y+4, w-8, h-8);
            
          }
          for (var i=0; i<CardBoard.cards.length; i++)
          {
            var index = CardBoard.cards[i].i;
            var worldPos = CardBoard.getWorldPos(index);
            
            
            var colorVal = 0.0;
            if (CardBoard.turn == CardBoard.cards[i].v)
            {
              colorVal = colorVal+0.6;
            }
            if (CardBoard.cards[i].t == 1)
            {
              colorVal = colorVal+0.2;
            }
            if (CardBoard.selected == i)
            {
              colorVal = colorVal+0.2;
            }
            else
            {
              var lerpVal = 0.8;
              CardBoard.cards[i].p.x = CardBoard.cards[i].p.x*lerpVal + worldPos.x*(1-lerpVal);
              CardBoard.cards[i].p.y = CardBoard.cards[i].p.y*lerpVal + worldPos.y*(1-lerpVal); 
            }
            var pos = CardBoard.cards[i].p;
            
            if (CardBoard.cards[i].v == 0)
            {
              ctx.fillStyle = "rgb("+Math.floor(colorVal*255) + ","+Math.floor(colorVal*100) +","+Math.floor(colorVal*100) +")";
            }
            else
            {
              ctx.fillStyle = "rgb("+Math.floor(colorVal*100) + ","+Math.floor(colorVal*255) + ","+Math.floor(colorVal*100) +")";
            }
            ctx.fillRect(pos.x+4, pos.y+4, w-8, h-8);
            
            ctx.font = "12px sans serif";
            ctx.fillStyle = "#000000";
            ctx.textAlign = "center";
            ctx.textBaseline = "middle"; 
            ctx.fillText("i"+i, pos.x+w*0.5, pos.y+h*0.5);
          }
          
        }
      }
      CardBoard.init();
    </script>
  </body>
</html>
